home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_022 / lemacs / termio.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  12KB  |  458 lines

  1. /*
  2.  * The functions in this file negotiate with the operating system for
  3.  * characters, and write characters in a barely buffered fashion on the display.
  4.  * All operating systems.
  5.  */
  6. #include        <stdio.h>
  7. #include    "estruct.h"
  8. #include        "edef.h"
  9.  
  10. #if     AMIGA
  11. #define NEW 1006
  12. #define AMG_MAXBUF      1024
  13. static long terminal;
  14. static char     scrn_tmp[AMG_MAXBUF+1];
  15. static int      scrn_tmp_p = 0;
  16. #endif
  17.  
  18. #if     VMS
  19. #include        <stsdef.h>
  20. #include        <ssdef.h>
  21. #include        <descrip.h>
  22. #include        <iodef.h>
  23. #include        <ttdef.h>
  24.  
  25. #define NIBUF   128                     /* Input buffer size            */
  26. #define NOBUF   1024                    /* MM says bug buffers win!     */
  27. #define EFN     0                       /* Event flag                   */
  28.  
  29. char    obuf[NOBUF];                    /* Output buffer                */
  30. int     nobuf;                  /* # of bytes in above    */
  31. char    ibuf[NIBUF];                    /* Input buffer          */
  32. int     nibuf;                  /* # of bytes in above  */
  33. int     ibufi;                  /* Read index                   */
  34. int     oldmode[2];                     /* Old TTY mode bits            */
  35. int     newmode[2];                     /* New TTY mode bits            */
  36. short   iochan;                  /* TTY I/O channel             */
  37. #endif
  38.  
  39. #if     CPM
  40. #include        <bdos.h>
  41. #endif
  42.  
  43. #if     MSDOS & LATTICE
  44. #undef  LATTICE
  45. #undef    CPM
  46. #include        <dos.h>
  47. #undef    CPM
  48. union REGS rg;        /* cpu register for use of DOS calls */
  49. int nxtchar = -1;    /* character held from type ahead    */
  50. #endif
  51.  
  52. #if    MSDOS & AZTEC
  53. struct regs {        /* cpu register for use of DOS calls */
  54.     int ax, bx, cx, dx, si, di, ds, es; } rg;
  55. int nxtchar = -1;    /* character held from type ahead    */
  56. #endif
  57.  
  58. #if RAINBOW
  59. #include "rainbow.h"
  60. #endif
  61.  
  62. #if V7
  63. #undef    CTRL
  64. #include        <sgtty.h>        /* for stty/gtty functions */
  65. #include    <signal.h>
  66. struct  sgttyb  ostate;          /* saved tty state */
  67. struct  sgttyb  nstate;          /* values for editor mode */
  68. struct tchars    otchars;    /* Saved terminal special character set */
  69. struct tchars    ntchars = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  70.                 /* A lot of nothing */
  71. #if BSD
  72. #include <sys/ioctl.h>        /* to get at the typeahead */
  73. extern    int rtfrmshell();    /* return from suspended shell */
  74. #define    TBUFSIZ    128
  75. char tobuf[TBUFSIZ];        /* terminal output buffer */
  76. #endif
  77. #endif
  78.  
  79. /*
  80.  * This function is called once to set up the terminal device streams.
  81.  * On VMS, it translates TT until it finds the terminal, then assigns
  82.  * a channel to it and sets it raw. On CPM it is a no-op.
  83.  */
  84. ttopen()
  85. {
  86. #if     AMIGA
  87.         terminal = Open("RAW:1/1/639/199/MicroEMACS 3.6/Amiga", NEW);
  88. #endif
  89. #if     VMS
  90.         struct  dsc$descriptor  idsc;
  91.         struct  dsc$descriptor  odsc;
  92.         char    oname[40];
  93.         int     iosb[2];
  94.         int     status;
  95.  
  96.         odsc.dsc$a_pointer = "TT";
  97.         odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  98.         odsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  99.         odsc.dsc$b_class        = DSC$K_CLASS_S;
  100.         idsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  101.         idsc.dsc$b_class        = DSC$K_CLASS_S;
  102.         do {
  103.                 idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  104.                 idsc.dsc$w_length  = odsc.dsc$w_length;
  105.                 odsc.dsc$a_pointer = &oname[0];
  106.                 odsc.dsc$w_length  = sizeof(oname);
  107.                 status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  108.                 if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  109.                         exit(status);
  110.                 if (oname[0] == 0x1B) {
  111.                         odsc.dsc$a_pointer += 4;
  112.                         odsc.dsc$w_length  -= 4;
  113.                 }
  114.         } while (status == SS$_NORMAL);
  115.         status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  116.         if (status != SS$_NORMAL)
  117.                 exit(status);
  118.         status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  119.                           oldmode, sizeof(oldmode), 0, 0, 0, 0);
  120.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  121.                 exit(status);
  122.         newmode[0] = oldmode[0];
  123.         newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
  124.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  125.                           newmode, sizeof(newmode), 0, 0, 0, 0);
  126.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  127.                 exit(status);
  128. #endif
  129. #if     CPM
  130. #endif
  131.  
  132. #if     MSDOS & (HP150 == 0) & LATTICE
  133.     /* kill the ctrl-break interupt */
  134.     rg.h.ah = 0x33;        /* control-break check dos call */
  135.     rg.h.al = 1;        /* set the current state */
  136.     rg.h.dl = 0;        /* set it OFF */
  137.     intdos(&rg, &rg);    /* go for it! */
  138. #endif
  139.  
  140. #if     V7 | BSD
  141.         gtty(0, &ostate);                       /* save old state */
  142.         gtty(0, &nstate);                       /* get base of new state */
  143.         nstate.sg_flags |= RAW;
  144.         nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
  145.         stty(0, &nstate);                       /* set mode */
  146.     ioctl(0, TIOCGETC, &otchars);        /* Save old characters */
  147.     ioctl(0, TIOCSETC, &ntchars);        /* Place new character into K */
  148. #if    BSD
  149.     /* provide a smaller terminal output buffer so that
  150.        the type ahead detection works better (more often) */
  151.     setbuffer(stdout, &tobuf[0], TBUFSIZ);
  152.     signal(SIGTSTP,SIG_DFL);    /* set signals so that we can */
  153.     signal(SIGCONT,rtfrmshell);    /* suspend & restart emacs */
  154. #endif
  155. #endif
  156. }
  157.  
  158. /*
  159.  * This function gets called just before we go back home to the command
  160.  * interpreter. On VMS it puts the terminal back in a reasonable state.
  161.  * Another no-operation on CPM.
  162.  */
  163. ttclose()
  164. {
  165. #if     AMIGA
  166.         amg_flush();
  167.         Close(terminal);
  168. #endif
  169. #if     VMS
  170.         int     status;
  171.         int     iosb[1];
  172.  
  173.         ttflush();
  174.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  175.                  oldmode, sizeof(oldmode), 0, 0, 0, 0);
  176.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  177.                 exit(status);
  178.         status = SYS$DASSGN(iochan);
  179.         if (status != SS$_NORMAL)
  180.                 exit(status);
  181. #endif
  182. #if     CPM
  183. #endif
  184. #if     MSDOS & (HP150 == 0) & LATTICE
  185.     /* restore the ctrl-break interupt */
  186.     rg.h.ah = 0x33;        /* control-break check dos call */
  187.     rg.h.al = 1;        /* set the current state */
  188.     rg.h.dl = 1;        /* set it ON */
  189.     intdos(&rg, &rg);    /* go for it! */
  190. #endif
  191.  
  192. #if     V7
  193.         stty(0, &ostate);
  194.     ioctl(0, TIOCSETC, &otchars);    /* Place old character into K */
  195. #endif
  196. }
  197.  
  198. /*
  199.  * Write a character to the display. On VMS, terminal output is buffered, and
  200.  * we just put the characters in the big array, after checking for overflow.
  201.  * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  202.  * MS-DOS (use the very very raw console output routine).
  203.  */
  204. ttputc(c)
  205. #if     AMIGA
  206.         char c;
  207. #endif
  208. {
  209. #if     AMIGA
  210.         scrn_tmp[scrn_tmp_p++] = c;
  211.         if(scrn_tmp_p>=AMG_MAXBUF)
  212.                 amg_flush();
  213. #endif
  214. #if     VMS
  215.         if (nobuf >= NOBUF)
  216.                 ttflush();
  217.         obuf[nobuf++] = c;
  218. #endif
  219.  
  220. #if     CPM
  221.         bios(BCONOUT, c, 0);
  222. #endif
  223.  
  224. #if     MSDOS & CWC86
  225.         dosb(CONDIO, c, 0);
  226. #endif
  227.  
  228. #if    MSDOS & LATTICE
  229.     bdos(6, c, 0);
  230. #endif
  231.  
  232. #if    MSDOS & AZTEC
  233.     bdos(6, c, 0);
  234. #endif
  235.  
  236. #if RAINBOW
  237.         Put_Char(c);                    /* fast video */
  238. #endif
  239.  
  240. #if     V7
  241.         fputc(c, stdout);
  242. #endif
  243. }
  244.  
  245. #if    AMIGA
  246. amg_flush()
  247. {
  248.         if(scrn_tmp_p)
  249.                 Write(terminal,scrn_tmp,scrn_tmp_p);
  250.         scrn_tmp_p = 0;
  251. }
  252. #endif
  253.  
  254. /*
  255.  * Flush terminal buffer. Does real work where the terminal output is buffered
  256.  * up. A no-operation on systems where byte at a time terminal I/O is done.
  257.  */
  258. ttflush()
  259. {
  260. #if     AMIGA
  261.         amg_flush();
  262. #endif
  263. #if     VMS
  264.         int     status;
  265.         int     iosb[2];
  266.  
  267.         status = SS$_NORMAL;
  268.         if (nobuf != 0) {
  269.                 status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  270.                          iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  271.                 if (status == SS$_NORMAL)
  272.                         status = iosb[0] & 0xFFFF;
  273.                 nobuf = 0;
  274.         }
  275.         return (status);
  276. #endif
  277. #if     CPM
  278. #endif
  279. #if     MSDOS
  280. #endif
  281. #if     V7
  282.         fflush(stdout);
  283. #endif
  284. }
  285.  
  286. /*
  287.  * Read a character from the terminal, performing no editing and doing no echo
  288.  * at all. More complex in VMS that almost anyplace else, which figures. Very
  289.  * simple on CPM, because the system can do exactly what you want.
  290.  */
  291. ttgetc()
  292. {
  293. #if     AMIGA
  294.         char ch;
  295.         amg_flush();
  296.         Read(terminal, &ch, 1);
  297.         return(255 & (int)ch);
  298. #endif
  299. #if     VMS
  300.         int     status;
  301.         int     iosb[2];
  302.         int     term[2];
  303.  
  304.         while (ibufi >= nibuf) {
  305.                 ibufi = 0;
  306.                 term[0] = 0;
  307.                 term[1] = 0;
  308.                 status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  309.                          iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  310.                 if (status != SS$_NORMAL)
  311.                         exit(status);
  312.                 status = iosb[0] & 0xFFFF;
  313.                 if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  314.                         exit(status);
  315.                 nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  316.                 if (nibuf == 0) {
  317.                         status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  318.                                  iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  319.                         if (status != SS$_NORMAL
  320.                         || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
  321.                                 exit(status);
  322.                         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  323.                 }
  324.         }
  325.         return (ibuf[ibufi++] & 0xFF);    /* Allow multinational  */
  326. #endif
  327.  
  328. #if     CPM
  329.         return (biosb(BCONIN, 0, 0));
  330. #endif
  331.  
  332. #if RAINBOW
  333.         int Ch;
  334.  
  335.         while ((Ch = Read_Keyboard()) < 0);
  336.  
  337.         if ((Ch & Function_Key) == 0)
  338.                 if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
  339.                         Ch &= 0xFF;
  340.  
  341.         return Ch;
  342. #endif
  343.  
  344. #if     MSDOS & MWC86
  345.         return (dosb(CONRAW, 0, 0));
  346. #endif
  347.  
  348. #if    MSDOS & LATTICE
  349.     int c;        /* character read */
  350.     int flags;    /* cpu flags after dos call */
  351.  
  352.     /* if a char already is ready, return it */
  353.     if (nxtchar >= 0) {
  354.         c = nxtchar;
  355.         nxtchar = -1;
  356.         return(c);
  357.     }
  358.  
  359.     /* call the dos to get a char until one is there */
  360.     flags = 255;
  361.     while ((flags & 64) != 0) {    /* while we don't yet have a char */
  362.         rg.h.ah = 6;        /* dos Direct Console I/O call */
  363.         rg.h.dl = 255;        /*     console input */
  364.         flags = intdos(&rg, &rg);
  365.         c = rg.h.al;        /* grab the char */
  366.     }
  367.  
  368.     return(c & 255);
  369. #endif
  370.  
  371. #if    MSDOS & AZTEC
  372.     int c;        /* character read */
  373.     int flags;    /* cpu flags after dos call */
  374.  
  375.     /* if a char already is ready, return it */
  376.     if (nxtchar >= 0) {
  377.         c = nxtchar;
  378.         nxtchar = -1;
  379.         return(c);
  380.     }
  381.  
  382.     /* call the dos to get a char until one is there */
  383.     flags = 255;
  384.     while ((flags & 64) != 0) {    /* while we don't yet have a char */
  385.         rg.ax = 1536;        /* dos Direct Console I/O call */
  386.         rg.dx = 255;        /*     console input */
  387.         flags = sysint(33, &rg, &rg);
  388.         c = rg.ax & 255;    /* grab the char */
  389.     }
  390.  
  391.     return(c);
  392. #endif
  393.  
  394. #if     V7
  395.         return(127 & fgetc(stdin));
  396. #endif
  397. }
  398.  
  399. #if    TYPEAH
  400. /* typahead:    Check to see if any characters are already in the
  401.         keyboard buffer
  402. */
  403.  
  404. typahead()
  405.  
  406. {
  407. #if    MSDOS & LATTICE
  408.     int c;        /* character read */
  409.     int flags;    /* cpu flags from dos call */
  410.  
  411.     if (nxtchar >= 0)
  412.         return(TRUE);
  413.  
  414.     rg.h.ah = 6;    /* Direct Console I/O call */
  415.     rg.h.dl = 255;    /*         does console input */
  416.     flags = intdos(&rg, &rg);
  417.     c = rg.h.al;    /* grab the character */
  418.  
  419.     /* no character pending */
  420.     if ((flags & 64) != 0)
  421.         return(FALSE);
  422.  
  423.     /* save the character and return true */
  424.     nxtchar = c;
  425.     return(TRUE);
  426. #endif
  427.  
  428. #if    MSDOS & AZTEC
  429.     int c;        /* character read */
  430.     int flags;    /* cpu flags from dos call */
  431.  
  432.     if (nxtchar >= 0)
  433.         return(TRUE);
  434.  
  435.     rg.ax = 1536;    /* Direct Console I/O call */
  436.     rg.dx = 255;    /*         does console input */
  437.     flags = sysint(33, &rg, &rg);
  438.     c = rg.ax & 255; /* grab the character */
  439.  
  440.     /* no character pending */
  441.     if ((flags & 64) != 0)
  442.         return(FALSE);
  443.  
  444.     /* save the character and return true */
  445.     nxtchar = c;
  446.     return(TRUE);
  447. #endif
  448.  
  449. #if    V7 & BSD
  450.     int x;    /* holds # of pending chars */
  451.  
  452.     return((ioctl(0,FIONREAD,&x) < 0) ? 0 : x);
  453. #endif
  454.     return(FALSE);
  455. }
  456. #endif
  457.  
  458.